import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';

enum AddPhotoType { add, select, delete }

enum AddPhotoModel { radioModel, checkModel }

typedef AddPhotoCallback = Future<bool> Function(
    int index, List<int> indexes, AddPhotoType type);
typedef DragCallback<T> = bool Function(List<T> indexes);
typedef SelectIndexedWidgetBuilder = Widget Function(
    BuildContext context, int index, bool select);

class AddPhotoView extends StatefulWidget {
  final SelectIndexedWidgetBuilder itemBuilder;
  final int crossAxisCount;
  ///水平间距
  final double crossAxisSpacing;
  ///垂直间距
  final double mainAxisSpacing;
  final double childAspectRatio;
  ///左右间距
  final double leftRightSpace;
  final Widget? defaultChild;
  final List? dataSource;
  final int maxCount;
  final EdgeInsets? margin;
  final AddPhotoCallback callback;
  final AddPhotoModel model;
  final DragCallback? dragCallback;
  final bool isSelect;
  final Widget? deleteChild;
  final bool cancelTap;
  final bool? onlyAddSelect;
  final bool pointSelect; //true为点击再取消,false 只会存在一个
  ///提示文本
  final String? prompt;
  final bool hasSelect; //适配赵
  final List<int>? indexSelect;
  final Color? color;
  final bool showSort;
  final double? itemHeight;
  final bool hiddenAddBtn;
  final ScrollPhysics? physics;
  final double? screenWidth;

  const AddPhotoView({
    Key? key,
    required this.itemBuilder,
    required this.model,
    required this.callback,
    this.crossAxisCount = 4,
    this.crossAxisSpacing = 10,
    this.mainAxisSpacing = 10,
    this.childAspectRatio = 1.0,
    this.defaultChild,
    this.dataSource,
    this.maxCount = 8,
    this.margin,
    this.isSelect = false, //是否选中
    this.hasSelect = false,
    this.deleteChild,
    this.cancelTap = false,
    this.onlyAddSelect,
    this.pointSelect = true,
    this.prompt,
    this.indexSelect,
    this.color,
    this.showSort = false,
    this.dragCallback,
    this.itemHeight,
    this.hiddenAddBtn = true,
    this.physics,
    required this.leftRightSpace,
    this.screenWidth,
  }) : super(key: key);

  @override
  State<AddPhotoView> createState() => _AddPhotoViewState();
}

class _AddPhotoViewState extends State<AddPhotoView> {
  List<Map<String, dynamic>> _items = [];
  int _row = 1;
  double? _itemHeight;
  double? myHeight;
  int _currentIndex = 0;
  @override
  void initState() {
    if (widget.dataSource == null) {
      _addMap(0, widget.isSelect);
    } else {
      ///有添加按钮
      if (widget.defaultChild != null) {
        List<dynamic> data = ArithmeticUtil().removeNull(widget.dataSource);
        for (int i = 0; i < data.length; i++) {
          _addMap(i, widget.isSelect);
        }
        if (widget.onlyAddSelect != null) {
          _addMap(data.length, widget.onlyAddSelect!);
        } else {
          _addMap(data.length, widget.isSelect);
        }
      } else {
        List<dynamic> data = ArithmeticUtil().removeNull(widget.dataSource);
        if (widget.indexSelect != null) {
          for (int i = 0; i < data.length; i++) {
              if (widget.indexSelect!.contains(i)) {
                _addMap(i, !widget.isSelect);
              } else {
                _addMap(i, widget.isSelect);
              }

          }
          return;
        }
        for (int i = 0; i < data.length; i++) {
            _addMap(i, widget.isSelect);
        }
      }
    }
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    bool hiddenBtn = false;
    if (_items.length - 1 == widget.maxCount && widget.hiddenAddBtn) {
      _items.removeLast();
      hiddenBtn = true;
    }
    // if (widget.dataSource?.length == widget.maxCount  && widget.hiddenAddBtn) {
    //   _items.removeLast();
    //   hiddenBtn = true;
    // }
    int row = _items.length ~/ widget.crossAxisCount;
    if (_items.length % widget.crossAxisCount != 0) {
      row += 1;
    }
    _row = row;
    if (_row == 0) {
      _row = 1;
    }
    double levelSpace = widget.leftRightSpace;
    if (widget.margin != null) {
      levelSpace = widget.margin!.left + widget.margin!.right;
    }
    //注意 抽屉屏幕这高度不准,因为不能根据整体屏幕来算 抽屉width是304
    double itemHeight = ((widget.screenWidth ?? ScreenUtil().screenWidth) -
            levelSpace -
            widget.crossAxisSpacing * (widget.crossAxisCount - 1)) /
        widget.crossAxisCount /
        widget.childAspectRatio;
    _itemHeight = itemHeight;
    double height = _row * itemHeight + (_row - 1) * widget.mainAxisSpacing;
    if (widget.itemHeight != null) {
      height = widget.itemHeight!;
    }

    _replaceMap();
    return Container(
        color: widget.color ?? Colors.transparent,
        height: height,
        margin: widget.margin,
        child: GridView.builder(
          physics: widget.physics ?? const NeverScrollableScrollPhysics(),
          padding: EdgeInsets.zero,
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: widget.crossAxisCount,
              crossAxisSpacing: widget.crossAxisSpacing,
              mainAxisSpacing: widget.mainAxisSpacing,
              childAspectRatio: widget.childAspectRatio),
          itemBuilder: (context, index) {
            Widget child;
            _currentIndex = index;
            ///代表是添加
            bool onlyOne = false;
            bool isSelect = _items[index]["isSelect"];
            if (widget.defaultChild != null && index == _items.length - 1) {
              if (hiddenBtn == false) {
                child = widget.defaultChild!;
                onlyOne = true;
              } else {
                child = widget.itemBuilder(context, index, isSelect);
                if (widget.showSort) {
                  child = addDragDrop(child, _items[index], index);
                  return child;
                }
              }
            } else if (widget.itemBuilder != null) {
              child = widget.itemBuilder(context, index, isSelect);
              if (widget.showSort) {
                child = addDragDrop(child, _items[index], index);
                return child;
              }
            } else {
              child = Container(
                color: Colors.green,
              );
            }
            if (widget.deleteChild != null && onlyOne == false) {
              child = Stack(
                fit: StackFit.expand,
                children: [
                  child,
                  Align(
                      alignment: Alignment.topRight,
                      child: GestureDetector(
                        child: widget.deleteChild,
                        onTap: () async {
                          bool isDelete =
                              await _handleCallback(index, AddPhotoType.delete);
                          if (isDelete) {
                            print("删除前长度 ${ _items.length}");
                            if(widget.dataSource?.length != widget.maxCount) {
                              _items.removeAt(index);
                            }
                            widget.dataSource?.removeAt(index);
                            print("删除item后长度 ${ _items.length}  datasoue = ${ widget.dataSource?.length}");
                            setState(() {});
                          }
                        },
                      )),
                ],
              );
            }
            return GestureDetector(
                behavior: HitTestBehavior.opaque,
                onTap: () async {
                  if (onlyOne == true) {
                    if (_items.length > widget.maxCount) {
                      // XCToast.show( widget.prompt ?? "超过最大数");
                      return;
                    }
                    if (await _handleCallback(index, AddPhotoType.add) ==
                        true) {
                      if (_items.length <= widget.maxCount) {
                        _addMap(_items.length,
                            widget.onlyAddSelect ?? widget.isSelect,
                            value: widget.dataSource?[index]);
                        setState(() {});
                      }
                    }
                    return;
                  }
                  if (widget.cancelTap) {
                    return;
                  }
                  bool oldSel = _items[index]["isSelect"];
                  if (widget.model == AddPhotoModel.checkModel) {
                    //多选

                    _items[index]["isSelect"] = !_items[index]["isSelect"];
                  } else {
                    if (widget.pointSelect == true) {
                      bool temp = _items[index]["isSelect"];
                      for (var element in _items) {
                        element["isSelect"] = false;
                      }
                      _items[index]["isSelect"] = !temp;
                    } else {
                      for (var element in _items) {
                        element["isSelect"] = false;
                      }
                      _items[index]["isSelect"] = true;
                    }
                  }
                  _handleCallback(index, AddPhotoType.select).then((value) {
                    if (value) {
                      setState(() {});
                    } else {
                      _items[index]["isSelect"] = oldSel;
                    }
                  });
                },
                child: child);
          },
          itemCount: _items.length,
        ));
  }

  void _addMap(int index, bool isSelect, {dynamic value}) {
    Map<String, dynamic> temp = {"index": index, "isSelect": isSelect};
    if (value != null) {
      temp["value"] = value;
    }
    _items.add(temp);
  }

  ///为了同步外层的index
  void _replaceMap()async{

    if (widget.model == AddPhotoModel.radioModel) {
        widget.indexSelect?.map((e){
          bool temp = _items[e]["isSelect"];
          // if (widget.pointSelect == true) {
          //   _items.map((e) => e["isSelect"] = false);
          //   _items[e]["isSelect"] = !temp;
          // }else{
          //   _items.map((e) => e["isSelect"] = false);
          //   _items[e]["isSelect"] = true;
          // }
          _items[e]["isSelect"] = true;
        });
      }else if(widget.model == AddPhotoModel.checkModel){
      widget.indexSelect?.map((e){
        _items[e]["isSelect"] = true;
      });
    }
  }

  Future<bool> _handleCallback(int index, AddPhotoType type) async {
    List<int> indexes = [];
    if (widget.model == AddPhotoModel.checkModel) {
      ///多选回调
      for (var e in _items) {
        int a = e["index"];
        if (e["isSelect"] == true) {
          indexes.add(a);
        }
      }
    } else {
      if (widget.pointSelect == true) {
        for (var e in _items) {
          int a = e["index"];
          if (e["isSelect"] == true) {
            indexes.add(a);
          }
        }
      } else {
        indexes = [index];
      }
    }
    return widget.callback(index, indexes, type);
  }

  dynamic _movingValue;

  Widget addDragDrop(Widget child, dynamic value, int index) {
    return LongPressDraggable(
      child: DragTarget(
        onAccept: (moveData) {
          if (kDebugMode) {
            print('=== onAccept: $moveData ==> $value');
          }
          exchangeItem(moveData, value, true, index);
        },
        onLeave: (moveData) {
          // print('=== onLeave: $moveData ==> $value');
        },
        onWillAccept: (moveData) {
          if (kDebugMode) {
            print('=== onWillAccept: $moveData ==> $value');
          }
          var accept = moveData != null;
          if (accept) {
            exchangeItem(moveData, value, false, index);
          }
          return accept;
        },
        builder: (context, data, rejects) {
          return baseItem(value, Colors.blue, child);
        },
      ),
      data: value,
      feedback: baseItem(value, Colors.green.withOpacity(0.8), child),
      onDragStarted: () {
        //开始拖动，备份数据源
        // print('=== onDragStarted');
        setState(() {
          _movingValue = value;
        });
      },
      onDraggableCanceled: (Velocity velocity, Offset offset) {
        // print('=== onDraggableCanceled');
        setState(() {
          _movingValue = null; //清空标记进行重绘
        });
      },
      onDragCompleted: () {
        // print('=== onDragCompleted');
      },
    );
  }

  // 重新排序
  void exchangeItem(moveData, toData, onAccept, int index) {
    setState(() {
      var toIndex = _items.indexOf(toData);
      _items.remove(moveData);
      _items.insert(toIndex, moveData);

      if (widget.dataSource != null) {
        if (onAccept && widget.dragCallback != null) {
          var temp = [];
          temp.addAll(_items);
          temp.removeWhere((element) => element["index"] == 0);
          var real = temp.map((e) => e["value"]).toList();
          widget.dragCallback!(real);
        }
      }
      if (onAccept) {
        _movingValue = null;
      }
    });
  }

  Widget baseItem(value, bgColor, Widget child) {
    if (value == _movingValue) {
      return Container();
    }
    return Container(
      width: 110,
      height: 110,
      color: bgColor,
      child: child,
    );
  }
}

class ArithmeticUtil<T>{
  T removeNull( T para){
    if(para is Map){
      para.removeWhere((key, value){
        if(value is List<Map<String,dynamic>>){
          for(Map<String,dynamic> item in value){
            item.removeWhere((key, value) => value == null);
          }
        }
        if(value is Map<String,dynamic>){
          value.removeWhere((key1, value1) => value1 == null);
          return false;
        }
        if(value == null){
          return true;
        }
        return false;
      });
      return para;
    }else if(para is List<dynamic>){
      para.remove(null);
    }
    return para;
  }
}
